/*
 * @Author: yanjikun
 * @Date: 2022-04-14 17:25:32
 * @LastEditors: yanjikun
 * @LastEditTime: 2022-05-16 16:55:48
 * @Description: file content
 */

interface TreeHelperConfig {
  id: string
  children: string
  pid: string
}
const DEFAULT_CONFIG: TreeHelperConfig = {
  id: 'id',
  children: 'children',
  pid: 'parentId',
}

const getConfig = (config: Partial<TreeHelperConfig>) => Object.assign({}, DEFAULT_CONFIG, config)

/**
 * @description: 将list转成树形结构
 * @param {any} list 数组列表
 * @param {Partial<TreeHelperConfig>} config 字段配置
 * @author: yanjikun
 */
export function listToTree<T = any>(list: any[], config: Partial<TreeHelperConfig> = {}): T[] {
  const conf = getConfig(config) as TreeHelperConfig
  const nodeMap = new Map()
  const result: T[] = []
  const { id, children, pid } = conf

  for (const node of list) {
    node[children] = node[children] || []
    nodeMap.set(node[id], node)
  }
  for (const node of list) {
    const parent = nodeMap.get(node[pid])
    ;(parent ? parent[children] : result).push(node)
  }
  return result
}
/**
 * @description: 回显前设置选中的项
 * @param {number} checkedList 选中项的id
 * @param {any} options 树形结构的数据
 * @param {*} total 初始值
 * @param {TreeHelperConfig} config 字段配置
 * @author: yanjikun
 */
export const getCheckedKeys = (
  checkedList: number[],
  options: any[],
  total = [],
  config: Partial<TreeHelperConfig> = {},
) => {
  const conf = getConfig(config) as TreeHelperConfig
  const { id, children } = conf
  return options.reduce<number[]>((prev, curr) => {
    if (curr[children]?.length) {
      getCheckedKeys(checkedList, curr[children], total)
    } else {
      if (checkedList.includes(curr[id])) {
        prev.push(curr[id])
      }
    }
    return prev
  }, total)
}
/**
 * @description: 格式化设置选中的项
 * @param {number} checkedList 选中项的id
 * @param {any} options 树形结构的数据
 * @param {*} total 初始值
 * @param {TreeHelperConfig} config 字段配置
 * @author: yanjikun
 */
export const getRights = (
  checkedList: number[],
  options: any[],
  total = [],
  config: Partial<TreeHelperConfig> = {},
) => {
  const conf = getConfig(config) as TreeHelperConfig
  const { id, children } = conf
  return options.reduce<number[]>((prev, curr) => {
    if (curr[children]?.length) {
      getRights(checkedList, curr[children], total)
      if (curr[children].some((item: any) => checkedList.includes(item[id]))) {
        prev.push(curr[id])
      }
    } else {
      if (checkedList.includes(curr[id])) {
        prev.push(curr[id])
      }
    }
    return prev
  }, total)
}
